﻿using System;
using System.Collections.Generic;
using DimensionsHelper.Common.Contracts.DataCollector.Options;
using DimensionsHelper.Common.Contracts.Services;

namespace DimensionsHelper.Services.DataCollector.Options;

public class Validator : IProjectService
{

    public string Section => "Validator";
        
    public IFilePikerService? FilePikerService { get; set; }
        
    public IReportService? ReportService { get; set; }

    private bool Validate(GroupType type)
    {
        if (string.IsNullOrEmpty(type.Name))
        {
            ReportService?.Error($"{nameof(GroupType.Name)}: 类型名称未配置");
            return false;
        }

        if (type.Values.Count == 0)
        {
            ReportService?.Error($"{nameof(GroupType.Values)}: 类型'{type.Name}'的有效值未配置");
            return false;
        }

        return true;
    }

    private bool Validate(GroupTypes types)
    {
        if (string.IsNullOrEmpty(types.ColumnKey))
        {
            ReportService?.Error($"{nameof(GroupTypes.ColumnKey)}: 属性不可忽略");
            return false;
        }

        ValidateDictionary(types.Settings, Validate, nameof(GroupTypes.Settings), (name, t) => t.Name = name);

        if (!types.Settings.ContainsKey(types.ColumnKey))
        {
            ReportService?.Error($"{nameof(GroupTypes.ColumnKey)}: 未找到指定名称的有效类型配置");
            return false;
        }

        return true;
    }

    private bool Validate(Threshold threshold)
    {
        if (!double.IsNaN(threshold.Upper) || !double.IsNaN(threshold.Lower))
        {
            return true;
        }

        ReportService?.Error($"{nameof(Threshold)}: 属性'{nameof(Threshold.Lower)}'和'{nameof(Threshold.Upper)}'需要至少一个有效值");
        return false;

    }

    private bool Validate(Testing testing)
    {
        if (!string.IsNullOrEmpty(testing.Name))
        {
            return true;
        }

        ReportService?.Error($"{nameof(Testing)}: 配置'${nameof(Testing.Name)}'不可忽略");
        return false;
    }

    private bool Validate(Mark mark)
    {
        if (!string.IsNullOrEmpty(mark.Less) ||
            !string.IsNullOrEmpty(mark.Greater) ||
            !string.IsNullOrEmpty(mark.Fit))
        {
            return true;
        }

        ReportService?.Error(
            $"{nameof(Mark)}: 属性'{nameof(Mark.Less)}'、'{nameof(Mark.Greater)}'、'{nameof(mark.Fit)}'需要至少配置一个有效值");
        return false;
    }

    private bool Validate(GapIndex gapIndex)
    {
        if (gapIndex.RightIndex >= 0)
        {
            return true;
        }

        ReportService?.Error($"{nameof(GapIndex.RightIndex)}: 属性值需要是正整数");
        return false;
    }

    private bool Validate(Gap gap)
    {
        if (string.IsNullOrEmpty(gap.Type))
        {
            ReportService?.Log($"{nameof(Gap.Type)}: Gap计算类型名不可忽略");
            return false;
        }

        if (string.IsNullOrEmpty(gap.TypeValue))
        {
            ReportService?.Log($"{nameof(Gap.TypeValue)} : Gap计算类型值不可忽略");
            return false;
        }

        var indices = gap.Indices;
        var ub = indices.Count;

        for (var i = ub - 1; i >= 0; i--)
        {
            if (Validate(indices[i]))
            {
                continue;
            }

            indices.RemoveAt(i);
            ReportService?.Log($"{nameof(Gap.Indices)}: 已移除无效索引");
        }

        return true;
    }

    private bool Validate(Export export)
    {
        if (string.IsNullOrEmpty(export.Name))
        {
            ReportService?.Error($"{nameof(Export.Name)}: 属性不可忽略");
            return false;
        }

        if (export.Name.Length > 32)
        {
            ReportService?.Error($"{nameof(Export.Name)}: 字符串过长，应当小于等于32个字符");
            return false;
        }

        if (export.StartRow <= 0)
        {
            ReportService?.Error($"{nameof(Export.StartRow)}: 应当是正整数");
            return false;
        }

        if (export.StartColumn <= 0)
        {
            ReportService?.Error($"{nameof(Export.StartColumn)}: 应当是正整数");
            return false;
        }

        if (string.IsNullOrEmpty(export.ValueAt))
        {
            ReportService?.Error($"{nameof(Export.ValueAt)}: 属性不可忽略");
            return false;
        }

        if (export.Headers.Length == 0)
        {
            ReportService?.Error($"{nameof(Export.Headers)}: 未添加任何表头");
            return false;
        }

        return true;
    }

    private void ValidateDictionary<T>(IDictionary<string, T> dict, Func<T, bool> validate, string settingName,
        Action<string, T>? callback = null)
    {
        var keys = dict.Keys;
        foreach (var k in keys)
        {
            callback?.Invoke(k, dict[k]);
            if (string.IsNullOrEmpty(k))
            {
                dict.Remove(k);
                ReportService?.Log($"{settingName}: 配置名称不可忽略，已移除");
            }
            else if (!validate(dict[k]))
            {
                dict.Remove(k);
                ReportService?.Log($"{settingName}: 已移除名为'{k}'的无效配置");
            }
        }
    }

    public bool Validate(CollectorOptions options)
    {
        if (!Validate(options.Types))
        {
            return false;
        }

        ValidateDictionary(options.Gaps, Validate, nameof(CollectorOptions.Gaps), (name, obj) => obj.Name = name);
        ValidateDictionary(options.Testings, Validate, nameof(CollectorOptions.Testings),
            (name, obj) => obj.Name = name);
        ValidateDictionary(options.Marks, Validate, nameof(CollectorOptions.Marks), (name, obj) => obj.Name = name);
        ValidateDictionary(options.Thresholds, Validate, nameof(CollectorOptions.Thresholds),
            (name, obj) => obj.Name = name);
        ValidateDictionary(options.Exports, Validate, nameof(CollectorOptions.Exports),
            (name, obj) => obj.Name = name);

        return true;
    }
}